/*
 * @Author: wuqingchun
 * @Date: 2024-04-20 22:30:59
 * @Description: C++ 类和对象相关知识测试程序
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-04-23 13:45:47
 */
#include <iostream>

#include "shape_circle.h"
#include "class_derived.h"
#include "class_memory_layout.h"
#include "class_virtual_destruct.h"

// 多态测试，参数为基类的引用
void test_polymorphic(const ClassBase& refBase)
{
    refBase.ShowInfo();
}

// 多态测试，参数为基类的指针
void test_polymorphic(const ClassBase* pobjBase)
{
    pobjBase->ShowInfo();
}

// 测试类的基本特性(封装/继承/多态/抽象)
void test_encapsulation_inherit_polymorphic()
{
    // 访问控制权限测试
    ClassDerivedPrivate objDPrivate;
    ClassDerivedProtected objDProtected;
    ClassDerivedPublic objDPublic;
    
    std::cout << "    public: " << ClassBase::m_uiAtomicDerivedCount_public.load() << std::endl;

    // error: ‘std::atomic<unsigned int> ClassBase::m_uiAtomicDerivedCount_protected’ is protected within this context
    // std::cout << " protected: " << ClassBase::m_uiAtomicDerivedCount_protected.load() << std::endl;

    // error: ‘std::atomic<unsigned int> ClassBase::m_uiAtomicDerivedCount_private’ is private within this context
    // std::cout << "   private: " << m_uiAtomicDerivedCount_private.load() << std::endl;

    // 通过"类名::函数名"调用类的静态成员函数
    ClassBase::ShowDerivedCount();

    objDPrivate.ShowInfo();
    objDProtected.ShowInfo();
    objDPublic.ShowInfo();

    std::cout << "===============polymorphic (Base reference)======================" << std::endl;
    test_polymorphic(reinterpret_cast<const ClassBase&>(objDPrivate));
    test_polymorphic(reinterpret_cast<const ClassBase&>(objDProtected));
    test_polymorphic(reinterpret_cast<const ClassBase&>(objDPublic));


    std::cout << "================polymorphic (Base pointer)=====================" << std::endl;
    test_polymorphic(reinterpret_cast<const ClassBase*>(&objDPrivate));
    test_polymorphic(reinterpret_cast<const ClassBase*>(&objDProtected));
    test_polymorphic(reinterpret_cast<const ClassBase*>(&objDPublic));
}


// 测试对象的内存布局
void test_memory_layout()
{
    std::cout << "\n===============test_memory_layout=============" << std::endl;
    CMemoryLayout objMLayout;

    std::cout << "sizeof(CMemoryLayout) = " << sizeof(CMemoryLayout) << std::endl;
    std::cout << "sizeof(objMLayout) = " << sizeof(objMLayout) << std::endl;

    CMemoryLayoutDerived objDerived;
    std::cout << "sizeof(CMemoryLayoutDerived) = " << sizeof(CMemoryLayoutDerived) << std::endl;
    std::cout << "sizeof(objDerived) = " << sizeof(objDerived) << std::endl;
}


// 虚析构函数测试
void test_virtual_destruct()
{
    std::cout << "\n===============test_virtual_destruct=============" << std::endl;


    std::cout << "[1]" << std::endl;
    CDestructDerived* pobjDerived1 = new CDestructDerived();
    delete pobjDerived1;

    std::cout << "[2]" << std::endl;
    pobjDerived1 = new CDestructDerived();
    CDestructBase* pobjBase1 = reinterpret_cast<CDestructBase*>(pobjDerived1);
    // 基类的析构函数没有声明为虚函数,使用基类类型的指针销毁对象,只会调用基类的析构函数,不会调用子类的析构函数,造成子类对象的资源泄漏
    delete pobjBase1;

    std::cout << "[3]" << std::endl;
    CVritualDestructDerived* pobjDerived = new CVritualDestructDerived();
    delete pobjDerived;

    std::cout << "[4]" << std::endl;
    pobjDerived = new CVritualDestructDerived();
    CVritualDestructBase* pobjBase = reinterpret_cast<CVritualDestructBase*>(pobjDerived);
    // 基类析构函数声明为虚函数,使用基类类型的指针销毁对象,会同时调用基类和子类的析构函数,进行资源的正常释放
    delete pobjBase;
}

// 抽象类测试
void test_abstract_class()
{
    std::cout << "\n===============test_abstract_class=============" << std::endl;

    Circle objCircle;

    // 抽象类不能进行实例化
    // error: cannot declare variable ‘objSharp’ to be of abstract type ‘ISharp’
    //  note:   because the following virtual functions are pure within ‘ISharp’:
    //ISharp objSharp;
}

int main(int argc, char** argv)
{
    test_encapsulation_inherit_polymorphic();

    test_memory_layout();

    test_virtual_destruct();

    test_abstract_class();

    return 0;
}